package com.wbs.rest.resource;

import com.wbs.rest.config.SqlRestAutoBeanConfig;
import com.wbs.rest.model.SqlModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.core.LinkBuilderSupport;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import javax.servlet.http.HttpServletRequest;

public class SqlLinkBuilder  extends LinkBuilderSupport<SqlLinkBuilder> {



    SqlModel sqlModel;

    public SqlLinkBuilder(UriComponentsBuilder builder, SqlModel sqlModel) {
        super(builder);
        this.sqlModel = sqlModel;
    }

    public SqlLinkBuilder(UriComponents uriComponents) {
        super(uriComponents);
    }

    public static SqlLinkBuilder linkTo(SqlModel sqlModel) {
        Assert.notNull(sqlModel, "SqlModel must not be null!");
        return new SqlLinkBuilder(getBuilder(), sqlModel).slash(sqlModel.getBaseUri() + "/" + sqlModel.getMappingUri());
    }

    public Link withModel() {
        return this.withModel("self");
    }

    public Link withModel(String ref) {
        return super.withRel(ref).withMedia(SqlRestAutoBeanConfig.MEDIA_TYPE).withType(sqlModel.getSqlType()).withTitle(sqlModel.getTitle()).withDeprecation(sqlModel.getDescription());
    }


    @Override
    protected SqlLinkBuilder getThis() {
        return this;
    }

    @Override
    protected SqlLinkBuilder createNewInstance(UriComponentsBuilder uriComponentsBuilder) {
        return new SqlLinkBuilder(uriComponentsBuilder, sqlModel);
    }


    public UriComponentsBuilder toUriComponentsBuilder() {
        return UriComponentsBuilder.fromUri(this.toUri());
    }


    static UriComponentsBuilder getBuilder() {
        if (RequestContextHolder.getRequestAttributes() == null) {
            return UriComponentsBuilder.fromPath("/");
        } else {
            HttpServletRequest request = getCurrentRequest();
            UriComponentsBuilder builder = ServletUriComponentsBuilder.fromServletMapping(request);
            String forwardedSsl = request.getHeader("X-Forwarded-Ssl");
            ForwardedHeader forwarded = ForwardedHeader.of(request.getHeader(ForwardedHeader.NAME));
            String proto = StringUtils.hasText(forwarded.getProto()) ? forwarded.getProto() : request.getHeader("X-Forwarded-Proto");
            if (!StringUtils.hasText(proto) && StringUtils.hasText(forwardedSsl) && forwardedSsl.equalsIgnoreCase("on")) {
                builder.scheme("https");
            }

            return builder;
        }
    }

    private static HttpServletRequest getCurrentRequest() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        Assert.state(requestAttributes != null, "Could not find current request via RequestContextHolder. Is this being called from a Spring MVC handler?");
        Assert.isInstanceOf(ServletRequestAttributes.class, requestAttributes);
        HttpServletRequest servletRequest = ((ServletRequestAttributes)requestAttributes).getRequest();
        Assert.state(servletRequest != null, "Could not find current HttpServletRequest");
        return servletRequest;
    }

    public static Link getDefaultSelfLink() {
        return new Link(ServletUriComponentsBuilder.fromCurrentRequest().build().toUriString());
    }

}

